﻿//_______________________________________________________________________________________________________________________
// Copy Right (c) 2010, 2011 SapiensIT Consulting GmbH, all rights reserved
//_______________________________________________________________________________________________________________________
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//_______________________________________________________________________________________________________________________
// PROJECT:     sapiens.at.SharePoint.QueryBuilder (SharePoint 2010/V4)
//_______________________________________________________________________________________________________________________
// VERSION:     2.0
//_______________________________________________________________________________________________________________________
// DESCRIPTION: 
//_______________________________________________________________________________________________________________________
// LICENSE:     Different licens Types apply to different file types:
//               - Source code files are governed by the MICROSOFT PUBLIC LICENSE (Ms-PL)
//               - Binary files are governed by MSDN CODE GALLERY BINARY LICENSE
//               - Documentation files are governed by CREATIVE COMMONS ATTRIBUTION 3.0 LICENSE
//
//               The licenses can be found at the projects source location.
//               If you do not agree, don't use it!
// 
//_______________________________________________________________________________________________________________________
// Start SharePoint Branding, visit http://www.cliggin.com! Visit us on http://www.sapiens.at! Tell your friends! 
//_______________________________________________________________________________________________________________________
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Utilities;

namespace Sapiens.at.SharePoint.Utils
{
    /// <summary>
    /// Represents a CAML expression.
    /// </summary>
    /// <remarks>
    /// If you want to compare the id of a lookup field set <see cref="IsLookup"/> to true.
    /// </remarks>
    /// <typeparam name="T">The type of the <see cref="Value"/> to compare</typeparam>
    public class QueryBuilderValueOperator<T> : QueryBuilderOperator
    {
        /// <summary>
        /// Gets or sets the value to compare.
        /// </summary>
        public T Value { get; set; }

        /// <summary>
        /// Gets or sets whether this field is a lookup field and the comparison is done using a lookupid.
        /// </summary>
        public bool IsLookup { get; set; }

        /// <summary>
        /// Instantiates a new operator.
        /// </summary>
        /// <param name="type">The <see cref="QueryBuilderOperator.Type"/> of the expression</param>
        /// <param name="fieldRef">The <see cref="QueryBuilderOperator.FieldRef"/> of the expression</param>
        /// <param name="value">The <see cref="Value"/> to compare</param>
        public QueryBuilderValueOperator(string type, string fieldRef, T value)
            : this(type, fieldRef, value, false) { }

        /// <summary>
        /// Instantiates a new operator.
        /// </summary>
        /// <param name="type">The <see cref="QueryBuilderOperator.Type"/> of the expression</param>
        /// <param name="fieldRef">The <see cref="QueryBuilderOperator.FieldRef"/> of the expression</param>
        /// <param name="value">The <see cref="Value"/> to compare</param>
        /// <param name="isLookup">Indicates whether the field is a lookup-field</param>
        public QueryBuilderValueOperator(string type, string fieldRef, T value, bool isLookup)
            :base(type, fieldRef)
        {
            if (value == null) { throw new ArgumentNullException("value"); }
            Value = value;
            IsLookup = isLookup;
        }

        /// <summary>
        /// Converts the expression into the CAML representation.
        /// </summary>
        /// <returns>The CAML query for this expression</returns>
        public override string ToString()
        {
            return string.Format("<{0}><FieldRef Name=\"{1}\"{2}/><Value Type=\"{3}\">{4}</Value></{0}>",
                Type,
                FieldRef,
                IsLookup ? " LookupId=\"TRUE\"" : string.Empty,
                GetCamlDataType(),
                GetCamlValue());
        }

        /// <summary>
        /// Returns the string for the Type attribute of the resulting CAML string.
        /// </summary>
        /// <remarks>
        /// Extend this if necessary!
        /// </remarks>
        /// <returns></returns>
        protected string GetCamlDataType()
        {
            if (IsLookup) { return "Lookup"; }

            var type = typeof(T);
            if (type == typeof(int)) { return "Integer"; }
            if (type == typeof(bool)) { return "Boolean"; }
            if (type == typeof(DateTime)) { return "DateTime"; }
            return "Text";
        }

        /// <summary>
        /// Returns the correctly formatted value to use in the CAML string.
        /// </summary>
        /// <returns></returns>
        protected string GetCamlValue()
        {
            if (Value is DateTime) { return SPUtility.CreateISO8601DateTimeFromSystemDateTime((Value as DateTime?).Value).ToString(); }
            if (Value is bool) { return (Value as bool?) == true ? "1" : "0"; }
            return Value.ToString();
        }
    }
}